package com.longcheer.weibo.vo;

import java.util.Date;
import java.util.List;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.json.JSONException;
import org.json.JSONObject;
import org.xml.sax.SAXException;

import com.longcheer.weibo.util.Utils;
import com.weibo.net.WeiboException;

public class Status extends Message implements java.io.Serializable {

    private static final long serialVersionUID = -978914534847703620L;
    
    private Date createdAt;             // 微博创建时间
    private long id;                    // 微博ID
    private String text;                // 微博内容
    private Status retweetedStatus;     // 转发的微博
    private Source source;              // 微博来源
    private boolean favorited;          // 是否已收藏
    private boolean truncated;          // 是否被截断 
    private long inReplyToStatusId;     // 回复ID
    private long inReplyToUserId;       // 回复人ID
    private String inReplyToScreenName; // 回复人昵称
    private String mid;                 // 微博MID
    private String bmiddlePic;          // 中等尺寸图片地址 
    private String originalPic;         // 原始图片地址 
    private String thumbnailPic;        // 缩略图片地址 
    private int repostsCount;           // 转发数
    private int commentsCount;          // 评论数 
    private List<Object> annotations;   // 微博附加注释信息 
    private GeoInfo geo;                // 地理信息字段 
    private User user;                  // 微博作者的用户信息字段
    
    private String localThumbnailPicPath;
    private String localOriginalPicPath;
    private String localBmiddlePicPath;
    
    public Status(JSONObject json) throws WeiboException {
        super(json);
        constructJson(json);
    }
    
    private void constructJson(JSONObject json) throws WeiboException {
        try {
            id = json.getLong("id");
            text = json.getString("text");
            if (!json.isNull("retweeted_status")) {
                JSONObject retweeted = json.getJSONObject("retweeted_status");
                retweetedStatus = new Status(retweeted);
            }
            source = new Source(json.getString("source"));
            favorited = Utils.getBoolean("favorited", json);
            truncated = Utils.getBoolean("truncated", json);
            createdAt = Utils.parseDate(json.getString("created_at"), "EEE MMM dd HH:mm:ss z yyyy");
            inReplyToStatusId = Utils.getLong("in_reply_to_status_id", json);
            inReplyToUserId = Utils.getLong("in_reply_to_user_id", json);
            inReplyToScreenName = json.getString("in_reply_to_screen_name");
            mid = json.getString("mid");
            if (json.has("bmiddle_pic"))
                bmiddlePic = json.getString("bmiddle_pic");
            if (json.has("original_pic"))
                originalPic = json.getString("original_pic");
            if (json.has("thumbnail_pic"))
                thumbnailPic = json.getString("thumbnail_pic");
            repostsCount = Utils.getInt("reposts_count", json);
            commentsCount = Utils.getInt("comments_count", json);

            if (json.has("geo")) {
                String geoStr = json.getString("geo");
                if(!Utils.isEmpty(geoStr) && !"null".equals(geoStr)){
                    geo = getGeoInfo(geoStr);
                }
            }
            if(!json.isNull("user"))
                user = new User(json.getJSONObject("user"));

        } catch (JSONException je) {
            throw new WeiboException(je.getMessage() + ":" + json.toString(), je);
        }
    }
    
    private GeoInfo getGeoInfo(String geo) {
        StringBuilder value= new StringBuilder();
        
        double latitude = 0.0;
        double longitude = 0.0;
        for (char c : geo.toCharArray()) {
            if (c > 45 && c < 58) {
                value.append(c);
            }
            if (c == 44) {
                if (value.length() > 0) {
                    latitude = Double.parseDouble(value.toString());
                    value.delete(0, value.length());
                }
            }
        }
        longitude = Double.parseDouble(value.toString());
        return new GeoInfo(latitude, longitude);
    }
    
    @Override
    public MessageType getType() {
        return MessageType.MSG_STATUS;
    }
    
    public static class GeoInfo implements java.io.Serializable {
        private static final long serialVersionUID = 7874710226528639530L;
        
        private double latitude;
        private double longitude;
        
        public GeoInfo(double latitude, double longitude) {
            this.latitude = latitude;
            this.longitude = longitude;
        }

        public double getLatitude() {
            return latitude;
        }

        public double getLongitude() {
            return longitude;
        }
    }
    
    public static class Source implements java.io.Serializable {
        private static final long serialVersionUID = 4364254386125882665L;
        
        private String url;
        private String show;
        private String source;
        
        public Source(String source) {
            this.source = source;
            parse();
        }
        
        private void parse() {
            if (source.startsWith("<a")) {
                String body = source.substring(source.indexOf('>')+1);
                show = body.substring(0, body.indexOf('<'));
                
                // TODO 处理href属性
            }
            
        }

        public String getUrl() {
            return url;
        }

        public String getShow() {
            return show;
        }

        public String getSource() {
            return source;
        }
    }

    @Override
    public Date getCreatedAt() {
        return createdAt;
    }

    @Override
    public long getId() {
        return id;
    }

    public String getText() {
        return text;
    }
    
    public Status getRetweetedStatus() {
        return retweetedStatus;
    }

    public void setRetweetedStatus(Status retweetedStatus) {
        this.retweetedStatus = retweetedStatus;
    }

    public Source getSource() {
        return source;
    }

    public boolean isFavorited() {
        return favorited;
    }

    public boolean isTruncated() {
        return truncated;
    }

    public long getInReplyToStatusId() {
        return inReplyToStatusId;
    }

    public long getInReplyToUserId() {
        return inReplyToUserId;
    }

    public String getInReplyToScreenName() {
        return inReplyToScreenName;
    }

    public String getMid() {
        return mid;
    }

    public String getBmiddlePic() {
        return bmiddlePic;
    }

    public String getOriginalPic() {
        return originalPic;
    }

    public String getThumbnailPic() {
        return thumbnailPic;
    }

    public int getRepostsCount() {
        return repostsCount;
    }

    public int getCommentsCount() {
        return commentsCount;
    }

    public List<Object> getAnnotations() {
        return annotations;
    }

    public GeoInfo getGeo() {
        return geo;
    }

    public User getUser() {
        return user;
    }

    public String getLocalThumbnailPicPath() {
        return localThumbnailPicPath;
    }

    public void setLocalThumbnailPicPath(String localThumbnailPicPath) {
        this.localThumbnailPicPath = localThumbnailPicPath;
    }

    public String getLocalOriginalPicPath() {
        return localOriginalPicPath;
    }

    public void setLocalOriginalPicPath(String localOriginalPicPath) {
        this.localOriginalPicPath = localOriginalPicPath;
    }

    public String getLocalBmiddlePicPath() {
        return localBmiddlePicPath;
    }

    public void setLocalBmiddlePicPath(String localBmiddlePicPath) {
        this.localBmiddlePicPath = localBmiddlePicPath;
    }
}
